
#define rLCDCON1    (*(volatile unsigned *)0x4d000000)  //LCD control 1
#define rLCDCON2    (*(volatile unsigned *)0x4d000004)  //LCD control 2
#define rLCDCON3    (*(volatile unsigned *)0x4d000008)  //LCD control 3
#define rLCDCON4    (*(volatile unsigned *)0x4d00000c)  //LCD control 4
#define rLCDCON5    (*(volatile unsigned *)0x4d000010)  //LCD control 5
#define rLCDSADDR1  (*(volatile unsigned *)0x4d000014)  //STN/TFT Frame buffer start address 1
#define rLCDSADDR2  (*(volatile unsigned *)0x4d000018)  //STN/TFT Frame buffer start address 2
#define rLCDSADDR3  (*(volatile unsigned *)0x4d00001c)  //STN/TFT Virtual screen address set
#define rLCDINTPND  (*(volatile unsigned *)0x4d000054)  //LCD Interrupt pending
#define rLCDSRCPND  (*(volatile unsigned *)0x4d000058)  //LCD Interrupt source
#define rLCDINTMSK  (*(volatile unsigned *)0x4d00005c)  //LCD Interrupt mask
#define rTCONSEL    (*(volatile unsigned *)0x4d000060)  //LPC3600 Control

#define LCD_FRAMEBUFFER 0x33800000
#define LCD_WIDTH (240)
#define LCD_HEIGHT (320)
#define M5D(n) ((n) & 0x1fffff)	// To get lower 21bits

#define BLACK   0x00000000
#define RED     0x00FF0000
#define GREEN   0x0000FF00
#define BLUE    0x000000BB
#define WHITE   0xFFFFFFFF

typedef unsigned int U32;

void myTFT_Init(int vram_addr, int width, int height, int virtual_width, int virtual_height)
{
     // 24bpp TFT, ENVID=off
     rLCDCON1=(1<<8)|(0<<7)|(3<<5)|(13<<1)|0;
     rLCDCON2=((32-1)<<24)|((height-1)<<14)|((11-1)<<6)|((2-1)<<0);
     rLCDCON3=((48-1)<<19)|((width-1)<<8)|((16-1)<<0);
     rLCDCON4=(13<<8)|((96-1)<<0);
     rLCDCON5=(1<<11)|(1<<9)|(1<<8)|(1<<0);	// FRM5:6:5,HSYNC and VSYNC are inverted
     
     // BPP24BL:x,FRM565:x,INVVCLK:x,INVVLINE:x,INVVFRAME:x,INVVD:x,
     // INVVDEN:x,INVPWREN:x,INVLEND:x,PWREN:x,ENLEND:x,BSWP:x,HWSWP:x
     rLCDSADDR1=(((U32)vram_addr>>22)<<21)|M5D((U32)vram_addr>>1);
     rLCDSADDR2=M5D( ((U32)vram_addr+(virtual_width*height*2))>>1 );
     rLCDSADDR3=(((virtual_width-width)/1)<<11)|(width/1);
    
     rLCDINTMSK|=(3); // MASK LCD Sub Interrupt
     rTCONSEL&=~((1<<4)|1); // Disable LCC3600, LPC3600
	
     //Enable LCD POWER ENABLE Function
     rLCDCON5|=(1<<3);   			// PWREN
     rLCDCON5&=~(1<<5);   			// INVPWREN
     
     rLCDCON1|=1; // ENVID=ON
}	

void myTFT_Putpixel(int x, int y, int color)
{
     unsigned int addr;	       	
     
     addr=LCD_FRAMEBUFFER+(x+y*LCD_WIDTH)*4;
     *(volatile int*)(addr)=color;    
} 

int myTFT_Getpixel(int x, int y)
{
     unsigned int addr, tmp;	       	
    
     addr=LCD_FRAMEBUFFER+(x+y*LCD_WIDTH)*4;
     tmp=*(volatile short *)(addr);
     
     return (tmp);
} 

void clear_LCD(void)
{
	int i;
	for(i=0;i<LCD_WIDTH*LCD_HEIGHT*4;i+=4)
         *(volatile int *)(LCD_FRAMEBUFFER+i)=WHITE;
}

/* draw a vertical line */
void myTFT_DrawVLine(int x, int y1, int y2, int color)
{
    int i = 0;
    for (i = y1; i <= y2; i++) {
        myTFT_Putpixel(x, i, color);
    }
}

/* draw a horizontal line */
void myTFT_DrawHLine(int x1, int x2, int y, int color)
{
    int i = 0;
    for (i = x1; i <= x2; i++) {
        myTFT_Putpixel(i, y, color);
    }
}

void entry(void)
{
    myTFT_Init(LCD_FRAMEBUFFER, LCD_WIDTH, LCD_HEIGHT, LCD_WIDTH + 1, LCD_HEIGHT + 1);
    clear_LCD();

    myTFT_DrawVLine(50, 50, 100, BLUE);
    myTFT_DrawVLine(60, 50, 100, RED);
    myTFT_DrawVLine(70, 50, 100, GREEN);
    myTFT_DrawHLine(50, 100, 50, BLUE);
    myTFT_DrawHLine(50, 100, 60, GREEN);
    myTFT_DrawHLine(50, 100, 70, RED);
}
